package com.yht.redbook.count.biz.consumer;

import com.yht.framework.common.utils.JsonUtils;
import com.yht.redbook.count.biz.constant.MQConstants;
import com.yht.redbook.count.biz.constant.RedisKeyConstants;
import com.yht.redbook.count.biz.domain.mapper.UserCountDOMapper;
import com.yht.redbook.count.biz.model.dto.NoteOperateMqDTO;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Objects;

@Component
@RocketMQMessageListener(consumerGroup = "redbook_group_" + MQConstants.TOPIC_NOTE_OPERATE,
        topic = MQConstants.TOPIC_NOTE_OPERATE)
@Slf4j
public class CountNotePublishConsumer implements RocketMQListener<Message> {

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Resource
    private UserCountDOMapper userCountDOMapper;

    @Override
    public void onMessage(Message message) {
        String bodyStr = new String(message.getBody());
        String tags = message.getTags();

        log.info("==> CountNotePublishConsumer 消费了消息 {}, tags: {}", bodyStr, tags);

        // 根据 MQ 标签判断是发布消息还是删除消息
        if (Objects.equals(MQConstants.TAG_NOTE_PUBLISH, tags)) {
            handleNoteTagMessage(bodyStr, 1);
        } else if (Objects.equals(MQConstants.TAG_NOTE_DELETE, tags)) {
            handleNoteTagMessage(bodyStr, -1);
        }
    }

    /**
     * 发布、删除笔记
     *
     * @param bodyStr
     */
    private void handleNoteTagMessage(String bodyStr, long count) {
        NoteOperateMqDTO noteOperateMqDTO = JsonUtils.parseObject(bodyStr, NoteOperateMqDTO.class);

        if (Objects.isNull(noteOperateMqDTO)) return;

        Long creatorId = noteOperateMqDTO.getCreatorId();

        // 更新用户维度 Redis 中的计数 Hash
        String countUserKey = RedisKeyConstants.buildCountUserKey(creatorId);

        Boolean isCountUserExisted = redisTemplate.hasKey(countUserKey);

        // 若 Redis 中用户计数存在，才更新至缓存中，初始化 hash 的工作放在查询时
        if (Boolean.TRUE.equals(isCountUserExisted)) {
            redisTemplate.opsForHash().increment(countUserKey, RedisKeyConstants.FIELD_NOTE_TOTAL, count);
        }

        // 更新 数据库表
        userCountDOMapper.insertOrUpdateNoteTotalByUserId(count, creatorId);
    }
}
